package com.learning.task4;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 
 * @author AnND1
 * 
 */
public class MyHandler {
	private Map<Integer, Person> personList;
	private ConcurrentHashMap<Integer, Person> personConcurrentList;
	private final int NUM_PERSON = 4;// value need is 50 but use 4 to test
	private static final String CHAR_LIST = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
	private static final int NAME_LENGTH = 10;
	private static final int ADRESS_LENGTH = 15;
	private static final int MAX_AGE = 80;
	private static final int MIN_AGE = 15;

	public Map<Integer, Person> getPersonList() {
		return personList;
	}

	public void setPersonList(Map<Integer, Person> personList) {
		this.personList = personList;
	}

	public ConcurrentHashMap<Integer, Person> getPersonConcurrentList() {
		return personConcurrentList;
	}

	public void setPersonConcurrentList(
			ConcurrentHashMap<Integer, Person> personConcurrentList) {
		this.personConcurrentList = personConcurrentList;
	}

	/**
	 * time when use concurrent hashmap
	 */
	public void displayTime() {

	}

	/**
	 * use iterator to print list person
	 */
	public void displayPerson() {
		Set<Integer> keySet = personList.keySet();
		Iterator<Integer> keySetIterator = keySet.iterator();
		while (keySetIterator.hasNext()) {
			int key = keySetIterator.next();
			Person myPerson = personList.get(key);
			System.out.println("Name" + myPerson.getName());
			System.out.println("Adress" + myPerson.getAdress());
			System.out.println("Age" + myPerson.getAge());
		}
	}

	/**
	 * use foreach to print list person
	 */
	public void displayPerson1() {
		for (int key : personList.keySet()) {
			Person myPerson = personList.get(key);
			System.out.println("Name" + myPerson.getName());
			System.out.println("Adress" + myPerson.getAdress());
			System.out.println("Age" + myPerson.getAge());
		}
	}

	/**
	 * use iterator to print concurrent list
	 */
	public void displayPerson3() {
		Set<Integer> keySet = personConcurrentList.keySet();
		Iterator<Integer> keySetIterator = keySet.iterator();
		while (keySetIterator.hasNext()) {
			int key = keySetIterator.next();
			Person myPerson = personConcurrentList.get(key);
			System.out.println("Name:" + myPerson.getName());
			System.out.println("Adress :" + myPerson.getAdress());
			System.out.println("Age :" + myPerson.getAge());
		}
	}

	/**
	 * use for each to print concurrent list
	 */
	public void displayPerson4() {
		for (int key : personConcurrentList.keySet()) {
			Person myPerson = personConcurrentList.get(key);
			System.out.println("Name :" + myPerson.getName());
			System.out.println("Adress :" + myPerson.getAdress());
			System.out.println("Age :" + myPerson.getAge());
		}
	}

	/**
	 * initial Person
	 * 
	 * @return
	 */

	public Person generatePerson() {
		Person person = new Person();
		int age = randomAge(MIN_AGE, MAX_AGE);
		String name = randomName(NAME_LENGTH);
		String adress = randomName(ADRESS_LENGTH);
		person.setAge(age);
		person.setAdress(adress);
		person.setName(name);
		return person;
	}

	/**
	 * Generate person list
	 */
	public void generatePersonList() {
		personList = new HashMap<>();
		for (int i = 0; i < NUM_PERSON; i++) {
			Person e = generatePerson();
			personList.put(i, e);
		}
	}

	/**
	 * Generate person list using synchonouses
	 */
	public void generatePersonListSynchronouse() {
		double startTime = System.currentTimeMillis();
		double stopTime;
		personList = Collections
				.synchronizedMap(new HashMap<Integer, Person>());
		for (int i = 0; i < NUM_PERSON; i++) {
			Person e = generatePerson();
			personList.put(i, e);
		}
		stopTime = System.currentTimeMillis();
		System.out.println("Initial time for synchronouses hashmap :"
				+ (stopTime - startTime));
	}

	/**
	 * Generate person list using concurrent hashmap
	 */
	public void generateConcurentPersonList() {
		double startTime = System.currentTimeMillis();
		double stopTime;
		personConcurrentList = new ConcurrentHashMap<>();
		for (int i = 0; i < NUM_PERSON; i++) {
			Person e = generatePerson();
			personConcurrentList.put(i, e);
			// System.out.println("run");
		}
		stopTime = System.currentTimeMillis();
		System.out.println("Initial time for concurrent hashmap :"
				+ (stopTime - startTime));
	}

	/**
	 * create random string
	 * 
	 * @param length
	 * @return
	 */
	public String randomName(int length) {
		StringBuffer randStr = new StringBuffer();
		for (int i = 0; i < length; i++) {
			Random randomGenerator = new Random();
			int randomInt = randomGenerator.nextInt(CHAR_LIST.length());
			char ch = CHAR_LIST.charAt(randomInt);
			randStr.append(ch);
		}
		return randStr.toString();
	}

	/**
	 * Create random age
	 * 
	 * @param aStart
	 * @param aEnd
	 * @return
	 */
	private static int randomAge(int aStart, int aEnd) {
		Random random = new Random();
		long range = (long) aEnd - (long) aStart + 1;
		// compute a fraction of the range, 0 <= frac < range
		long fraction = (long) (range * random.nextDouble());
		int randomNumber = (int) (fraction + aStart);
		return randomNumber;
	}

	/**
	 * delete person from hashmap
	 */
	public void deletePerson(int key) {
		personList.remove(key);
	}

	/**
	 * delete person from hashmap
	 */
	public void deletePerson2(int key) {
		personConcurrentList.remove(key);
	}

	/**
	 * elete person from hashmap
	 */
	public void deletePerson3(int key) {
		Set<Integer> keySet = personConcurrentList.keySet();
		Iterator<Integer> keySetIterator = keySet.iterator();
		while (keySetIterator.hasNext()) {
			int key1 = keySetIterator.next();
			Person myPerson = personConcurrentList.get(key1);
			if(key1==key){
				personConcurrentList.remove(key);
				personConcurrentList.put(key1, myPerson);
			}
		}

	}

}
